package com.qianyu.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qianyu.config.Constants;
import com.qianyu.entity.base.BaseNotifyDto;
import com.qianyu.entity.bean.QqAccount;
import com.qianyu.entity.bean.QqAccountLog;
import com.qianyu.entity.bean.QunMember;
import com.qianyu.entity.bean.QunRedtail;
import com.qianyu.entity.dto.GiveHbNotifyDto;
import com.qianyu.entity.dto.QqMemberDto;
import com.qianyu.entity.vo.QqMemberVo;
import com.qianyu.entity.vo.QunMemberKeepQhVo;
import com.qianyu.mapper.QqAccountLogMapper;
import com.qianyu.mapper.QunMemberMapper;
import com.qianyu.service.QqAccountService;
import com.qianyu.service.QunMemberService;
import com.qianyu.service.QunRedtailService;
import com.qianyu.service.QunService;
import com.qianyu.util.CacheKeyUtil;
import com.qianyu.util.RedisUtil;
import com.qianyu.util.TimeUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
@RequiredArgsConstructor
public class QunMemberServiceImpl extends ServiceImpl<QunMemberMapper, QunMember> implements QunMemberService {

    private final QqAccountLogMapper qqAccountLogMapper;

    private final RedisUtil redisUtil;

    private final QqAccountService qqAccountService;

    private final QunRedtailService qunRedtailService;

    private final QunService qunService;

    /**
     * 加群取号
     */
    @Override
    public QqMemberVo joinQun() {
        QqMemberVo qqMemberVo = null;
        if (redisUtil.hasKey(CacheKeyUtil.addMembersToCacheSet())) {
            if (redisUtil.rGet(CacheKeyUtil.addMembersToCacheSet()) != null) {
                qqMemberVo = (QqMemberVo) redisUtil.rGet(CacheKeyUtil.addMembersToCacheSet());
            }
            return qqMemberVo;
        } else {
            qqMemberVo = baseMapper.joinQunOne(TimeUtil.toExpireDate(Constants.keepTimeHour, Calendar.MINUTE));
        }
        if (qqMemberVo != null) {
            update(Wrappers.<QunMember>lambdaUpdate().set(QunMember::getJoinTime, DateUtil.date()).eq(QunMember::getQq, qqMemberVo.getQq()));
        }
        return qqMemberVo;

    }

    /**
     * 加群回调
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean joinNotify(BaseNotifyDto dto) {
        LambdaQueryWrapper<QunMember> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(QunMember::getQq, dto.getQq());
        QunMember member = getOne(wrapper);
        switch (dto.getStatus()) {
            //账号冻结
            case -1:
                qqAccountService.freezeAccount(dto.getQq(), dto.getRemark());
                break;
            //失败
            case 0:
                member.setStatus(-1);
                break;
            case 1:
                member.setStatus(dto.getStatus());
                member.setJoinTime(DateUtil.date());
                member.setKeepGetTime(DateUtil.parse(TimeUtil.toExpireDate(Constants.keepGetTimeHour, Calendar.HOUR_OF_DAY)));
                member.setKeepTime(DateUtil.parse(TimeUtil.toExpireDate(Constants.keepTimeHour, Calendar.HOUR_OF_DAY)));
                member.setBaoId(UUID.randomUUID().toString());
                member.setRemark(dto.getRemark());
                //添加群日志
                QqAccountLog log = new QqAccountLog() {{
                    setQq(dto.getQq());
                    setQunId(member.getQunId());
                    setRemark("加群取号");
                    setKey("加群取号");
                }};
                qqAccountLogMapper.insert(log);

                //更新qq状态
                QqAccount account = qqAccountService.getOne(Wrappers.<QqAccount>lambdaQuery().eq(QqAccount::getQq, dto.getQq()));
                account.setQunNum(account.getQunNum() + 1);
                account.setLastQunId(member.getQunId());
                account.setSeatStatus(1);
                qqAccountService.updateById(account);
                //todo 调袁能接口
                break;
            default:
                break;
        }

        return updateById(member);
    }

    /**
     * 发红包保持取号
     */
    @Override
    public QunMemberKeepQhVo keepQh() {
        QunMemberKeepQhVo keepQhVo = null;
        if (redisUtil.hasKey(CacheKeyUtil.keepQhSet())) {
            if (redisUtil.rGet(CacheKeyUtil.keepQhSet()) != null) {
                keepQhVo = (QunMemberKeepQhVo) redisUtil.rGet(CacheKeyUtil.keepQhSet());
            } else {
                redisUtil.del(CacheKeyUtil.keepQhSet());
            }
        } else {

            keepQhVo = baseMapper.keepQhOne(TimeUtil.toExpireDate(Constants.keepTimeHour, Calendar.HOUR_OF_DAY),
                    TimeUtil.toExpireDate(Constants.keepGetTimeHour, Calendar.HOUR_OF_DAY));


        }
        if (keepQhVo != null) {
            update(Wrappers.<QunMember>lambdaUpdate().set(QunMember::getKeepGetTime, DateUtil.date())
                    .eq(QunMember::getQq, keepQhVo.getQq()));
        }

        List<QunMemberKeepQhVo> keepQhVos = baseMapper.keepQh(TimeUtil.toExpireDate(Constants.keepTimeHour, Calendar.HOUR_OF_DAY),
                TimeUtil.toExpireDate(Constants.keepGetTimeHour, Calendar.HOUR_OF_DAY));
        for (QunMemberKeepQhVo vo : keepQhVos) {
            redisUtil.lSet(CacheKeyUtil.keepQhSet(), vo);
        }
        if (redisUtil.hasKey(CacheKeyUtil.keepQhSet())) {
            redisUtil.expire(CacheKeyUtil.keepQhSet(), Constants.keepQhToCache);
        }

        return keepQhVo;
    }

    /**
     * 取号回调
     *
     * @param dto
     */
    @Override
    public boolean keepQhNotify(BaseNotifyDto dto) {
        LambdaUpdateWrapper<QunMember> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(QunMember::getQq, dto.getQq());
        switch (dto.getStatus()) {
            case -1:
                qqAccountService.freezeAccount(dto.getQq(), dto.getRemark());
                break;
            //失败
            case 0:
                break;
            case 1:
                wrapper.set(QunMember::getKeepTime, DateUtil.date());
                break;
        }

        return update(wrapper);
    }

    /**
     * 发红包回调
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean giveHbNotify(GiveHbNotifyDto dto) {
        LambdaQueryWrapper<QunMember> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(QunMember::getQq, dto.getQq());
        QunMember member = getOne(wrapper);
        member.setRedMoney(member.getRedMoney().add(new BigDecimal(dto.getMoney())));
        member.setRedNum(member.getRedNum() + 1);
        member.setLastRedTime(new Date());

        QunRedtail redtail = new QunRedtail() {{
            setQunId(member.getQunId());
            setQq(dto.getQq());
            setMoney(new BigDecimal(dto.getMoney()));
            setType(0);
        }};

        qunRedtailService.save(redtail);

        return updateById(member);
    }

    /**
     * 根据群id获取群成员
     *
     * @param dto
     */
    @Override
    public List<QunMember> getMemberList(QqMemberDto.QqMemberSearchDto dto) {
        return list(Wrappers.<QunMember>lambdaQuery().eq(ObjectUtil.isNotNull(dto.getStatus())
                        , QunMember::getStatus, dto.getStatus()).eq(QunMember::getQunId, dto.getId())
                .like(!StringUtils.isEmpty(dto.getQq()), QunMember::getQq, dto.getQq()));
    }
}
